<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */
declare (strict_types=1);

namespace app\madmin\service;

use app\madmin\model\MsgTemplate as admin;
use app\madmin\model\Configuration;
use app\madmin\model\WechatTemplate;
use app\madmin\model\WxTemplate as WxTemp;
use app\utils\TrimData;
use think\Exception;
use think\facade\Config;
use WeChat\Template as WxTemplate;
use WeMini\Template as WxaTemplate;
use think\facade\Db;

class MsgConfigService
{
    private $baseTemplate;

    private $scenarized;

    private $type;

    private $baseTemplateId;

    public function __construct()
    {
        $this->scenarized = Config::load('extension/scenarized', 'scenarized');
        $this->baseTemplate = Config::load('extension/baseTemplate', 'baseTemplate');
        $this->type = Config::load('extension/type', 'type');
        $this->baseTemplateId = Config::load('extension/templateId', 'baseTemplateId');
    }

    /**
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function index(string $type)
    {
        $typeArr = explode('->', $type);
        $base = $this->clearType($this->baseTemplate, $typeArr);
        $keys = array_keys($base);
        $msgTemplateList = admin::where("type", 'in', $keys)->select();

        return [HTTP_SUCCESS, ['base' => $base, 'msgTemplateList' => $msgTemplateList, 'type' => $this->type]];
    }

    private function clearType($base, $typeArr)
    {
        foreach ($typeArr as $type) {
            if (isset($base[$type])) {
                $base = $base[$type];
            }
        }
        return $base;
    }

    /**
     * 保存数据
     * @param array $data
     * @return array
     * @throws
     */
    public function save(array $data)
    {
        global $user;
        switch ($data['channel']) {
            // 微信公众号
            case 1:
                $templateApply = WxTemp::where([
                    'name' => $data['type'],
                    'channel' => 1
                ])->find();
                $result = self::addTemplate('wx', $templateApply['value']);
                if ($result['errcode'] != 0) {
                    return [HTTP_INVALID, $result['errmsg']];
                }

                $templateApply = $this->scenarized[$data['type']][$data['channel']]["template"]["data"];
                $attr = [];
                foreach ($templateApply as $tk => $tv) {
                    $other = ['first', 'remark'];
                    if (!in_array($tk, $other)) {
                        array_push($attr, $tv);
                    }
                }
                $inData = [
                    'scene' => $data['type'],
                    'name' => $data['timing'],
                    'template_id' => $result['template_id'],
                    'first' => $templateApply['first'],
                    'attr' => $attr,
                    'remark' => $templateApply["remark"],
                    'mall_id' => $user['mall_id'],
                    'status' => 1,
                ];
                $data['template_id'] = WechatTemplate::insertGetId($inData);
                break;
            case 2:
                $templateApply = WxTemp::where([
                    'name' => $data['type'],
                    'channel' => 2
                ])->find()->toArray();
                $result = self::addTemplate('wxa', $templateApply['value']);
                if ($result['errcode'] != 0) {
                    return [HTTP_INVALID, $result['errmsg']];
                }
                $inData = [
                    'scene' => $data['type'],
                    'name' => $data['timing'],
                    'template_id' => $result['priTmplId'],
                    'first' => "1",
                    'attr' => $templateApply['example'],
                    'remark' => "1",
                    'mall_id' => $user['mall_id'],
                    'status' => 1,
                ];
                $data['template_id'] = WechatTemplate::insertGetId($inData);
                break;
            case 3:
                $config = Configuration::where('type', 'aliSms')->find();
                $config['configuration']['accessKeyId'];
                if ($config['configuration']['accessKeyId'] == "" || $config['configuration']['accessSecret'] == "") {
                    return [HTTP_INVALID, "请先前往配置短信！"];
                }
                if (empty($data['template_id'])) {
                    return [HTTP_INVALID, "模版不可为空！"];
                }
                break;
        }
        $model = admin::create($data);
        return [HTTP_CREATED, $model];
    }

    /**
     * 获取微信模版id
     * @param $tpl_id 微信模版编号
     * @return array
     */
    public function wxTemplate($tpl_id)
    {
        $result = self::addTemplate('wx', $tpl_id);
        return [HTTP_SUCCESS, $result];
    }


    private function addTemplate($type, $tpl_id)
    {
        $configuration = Configuration::where(['type' => $type, 'status' => 1])->value('configuration');
        if (empty($configuration))
            throw new Exception("请先完成参数配", HTTP_INVALID);
        switch ($type) {
            case "wx":
                $configuration = is_array($configuration) ? $configuration : json_decode($configuration, true);
                $template = new WxTemplate($configuration);
                $result = $template->addTemplate($tpl_id);
                break;
            case "wxa":
                $configuration = is_array($configuration) ? $configuration : json_decode($configuration, true);
                $template = new WxaTemplate($configuration);
                $wxTem = WxTemp::where([
                    'channel' => 2,
                    'value' => $tpl_id
                ])->find()->toArray();
                $result = $template->newAddTemplate($tpl_id, explode(",", $wxTem['kid_list']), $wxTem['name']);
                break;
        }
//        if (isset($result['errcode']) && $result['errcode'] != 0)
//            throw new Exception("添加模板失败", HTTP_NOTACCEPT);
        return $result;
    }

    /**
     * 更新数据
     * @param int $id
     * @param array $data
     * @return array
     * @throws
     */
    public function update(int $id, array $data)
    {
        if (empty($data['template_id'])) {
            return [HTTP_INVALID, "模版不可为空！"];
        }
        $temp = WechatTemplate::find($data['template_id']);
        if (empty($temp) && ($data['channel'] == 1 || $data['channel'] == 2)) {
            return [HTTP_INVALID, "错误！"];
        }
        if ($temp['status'] != $data['status']) {
            if ($data['status'] == 1) {
                switch ($data['channel']) {
                    case 1:
                        $templateApply = $this->scenarized[$data['type']][$data['channel']]["template"]["data"];
                        $attr = [];
                        foreach ($templateApply as $tk => $tv) {
                            $other = ['first', 'remark'];
                            if (!in_array($tk, $other)) {
                                array_push($attr, $tv);
                            }
                        }
                        $update = [
                            'first' => $templateApply['first'],
                            'attr' => $attr,
                            'remark' => $templateApply["remark"],
                        ];
                        $wx = $this->delTemplate('wx', $temp['template_id']);
                        if (isset($wx['errcode']) && $wx['errcode'] == 0) {
                            $templateApply = WxTemp::where([
                                'name' => $data['type'],
                                'channel' => 1
                            ])->find();
                            $result = self::addTemplate('wx', $templateApply['value']);
                            if (isset($result['errcode']) && $result['errcode'] == 0) {
                                $update = array_merge($update, ['template_id' => $result['template_id'], 'status' => 1]);
                                WechatTemplate::update($update, ['id' => $data['template_id']]);
                            } else {
                                throw new Exception("更新模板id失败！" . $result['errmsg'], HTTP_NOTACCEPT);
                            }
                        } else {
                            throw new Exception("更新模板id失败！" . $wx['errmsg'], HTTP_NOTACCEPT);
                        }
                        break;
                    case 2:
                        $wxa = $this->delTemplate('wxa', $temp['template_id']);
                        if ($data['status'] == 1 && isset($wxa['errcode']) && $wxa['errcode'] == 0) {
                            $templateApply = WxTemp::where([
                                'name' => $data['type'],
                                'channel' => 2
                            ])->find();
                            $result = self::addTemplate('wxa', $templateApply['value']);
                            if (isset($result['errcode']) && $result['errcode'] == 0) {
                                WechatTemplate::update(['template_id' => $result['priTmplId']], ['id' => $data['template_id']]);
                            } else {
                                throw new Exception("更新模板id失败！" . $result['errmsg'], HTTP_NOTACCEPT);
                            }
                        } else {
                            throw new Exception("更新模板id失败！" . $wxa['errmsg'], HTTP_NOTACCEPT);
                        }
                        break;
                }
            } else {
                WechatTemplate::update(['status' => 0], ['id' => $data['template_id']]);
            }
        }
        $admin = admin::where('id', $id)
            ->save($data);
        return [HTTP_CREATED, $admin];
    }

    /**
     * 删除模版消息
     * @param $type string 类型
     * @param $tpl_id string 模版id
     * @return array
     * @throws
     */
    private function delTemplate($type, $tpl_id)
    {
        $configuration = Configuration::where(['type' => $type, 'status' => 1])->value('configuration');
        if (empty($configuration))
            throw new Exception("请先完成参数配", HTTP_INVALID);
        switch ($type) {
            case "wx":
                $configuration = is_array($configuration) ? $configuration : json_decode($configuration, true);
                $template = new WxTemplate($configuration);
                $temps = $template->getAllPrivateTemplate();
                $result = ['errcode' => 0];
                foreach ($temps['template_list'] as $key => $value) {
                    if ($value['template_id'] == $tpl_id) {
                        $result = $template->delPrivateTemplate($tpl_id);
                    }
                }
                break;
            case "wxa":
                $configuration = is_array($configuration) ? $configuration : json_decode($configuration, true);
                $template = new WxaTemplate($configuration);
                $result = $template->newDelTemplate($tpl_id);
                break;

        }

        return $result;
    }
    /**
     * 获取场景变量
     * @param $type
     * @return array
     */
    public function scene()
    {
        $scene = Config::load('extension/scene', 'scene');
        foreach ($scene as $k => $v) {
            $scene[$k] = array_keys($v);
        }
        return [HTTP_SUCCESS, $scene];
    }

//    /*
// * 拥有flag标记下的数组使用key
// */
//    function trimScene(&$array)
//    {
//        foreach ($array as $k => $v) {
//            if (isset($v['flag'])) {
//                unset($v['flag']);
//                $keys = array_keys($v);
//                $array[$k] = $keys;
//                continue;
//            }
//            $array[$k] = trimScene($v);
//        }
//        return $array;
//    }

    private function setWxaTemplateIdToFile(array $data)
    {
        $fopen = fopen("../../../config/extension/scenarized.php", 'r+');
        try {
            if (flock($fopen, LOCK_EX)) {
                ftruncate($fopen, 0);
                $str = "<?php" . "\r\n" . "return [" . "\r\n";
                foreach ($data as $k => $v) {
                    $str .= "\t\"$k\"=>" . "\"$v\"," . "\r\n";
                }
                $str .= "];";
                fwrite($fopen, $str);
                flock($fopen, LOCK_UN);
            }
            fclose($fopen);
        } catch (\Exception $e) {
            fclose($fopen);
            $this->setWxaTemplateIdToFile($data);
        }
    }

}
